package cn.edu.tju.elm.controller;

import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.core.model.User;
import cn.edu.tju.elm.dto.OrderResponseDTO;
import cn.edu.tju.elm.mapper.OrderMapper;
import cn.edu.tju.elm.model.Cart;
import cn.edu.tju.elm.model.Order;
//import cn.edu.tju.elb.service.OrderService;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.core.security.PermissionUtils;
import cn.edu.tju.elm.model.OrderDetailet;
import cn.edu.tju.elm.service.CartService;
import cn.edu.tju.elm.service.OrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/api/orders")
@Tag(name = "管理订单", description = "对订单进行增删改查")
public class OrderController {
    @Autowired
    private UserService userService;

    @Autowired
    private OrderService ordersService;

    @Autowired
    private CartService cartService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private PermissionUtils permissionUtils;

    @PostMapping(value = "")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "增加订单")
    public HttpResult<OrderResponseDTO> addOrders(@RequestBody Order order) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            Long businessId = order.getBusiness().getId();
            Long userId = user.getId();
            List<Cart> list = cartService.getAllCarts(userId, businessId);
            BigDecimal total = BigDecimal.ZERO;
            for (Cart c : list) {
                System.out.println("Cart food: " + c.getFood());
                OrderDetailet detail = new OrderDetailet();
                detail.setOrder(order);
                detail.setFood(c.getFood());
                detail.setQuantity(c.getQuantity());
                detail.setCreator(userId);
                detail.setCreateTime(LocalDateTime.now());
                detail.setUpdateTime(LocalDateTime.now());
                detail.setUpdater(userId);
                detail.setDeleted(false);
                order.getOrderDetailets().add(detail);
                BigDecimal itemPrice = c.getFood().getFoodPrice().multiply(new BigDecimal(c.getQuantity()));
                total = total.add(itemPrice);
            }
            LocalDateTime now = LocalDateTime.now();
            order.setCreator(user.getId());
            order.setCustomer(user);
            order.setCreateTime(now);
            order.setUpdater(user.getId());
            order.setUpdateTime(now);
            order.setDeleted(false);
            order.setOrderTotal(total);
            order.setOrderState(0); 
            Order o = ordersService.addOrder(order);
            Order fullOrder = orderService.getOrderById(o.getId()).get();
            for (OrderDetailet d : fullOrder.getOrderDetailets()) {
    System.out.println("OrderDetailet food: " + d.getFood());
}
            return HttpResult.success(orderMapper.toOrderResponseDTO(fullOrder));
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "创建订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or @permissionUtils.canAccessOrderData(@orderService.getOrderById(#id).get().getCustomer().getId())")
    @Operation(summary = "通过订单号获得订单")
    public HttpResult<OrderResponseDTO> getOrderById(@PathVariable Long id) throws Exception{
        try {
            Optional<Order> order = orderService.getOrderById(id);
            if (order.isPresent()) {
                OrderResponseDTO responseDTO = orderMapper.toOrderResponseDTO(order.get());
                return HttpResult.success(responseDTO);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "订单不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询订单失败: " + e.getMessage());
        }
    }

    @GetMapping("")
    @PreAuthorize("hasAuthority('ADMIN') or @permissionUtils.canAccessOrderData(#userId)")
    @Operation(summary = "通过用户id获得所有订单")
    public HttpResult<List<OrderResponseDTO>> listOrdersByUserId(@RequestParam Long userId) throws Exception{
        try {
            List<Order> orders = orderService.getOrdersByUserId(userId);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/current-user")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "查询当前用户的所有订单")
    public HttpResult<List<OrderResponseDTO>> getCurrentUserOrders() throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            List<Order> orders = orderService.getOrdersByUserId(user.getId());
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询当前用户订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/by-business/{businessId}")
    @PreAuthorize("hasAuthority('ADMIN') or (hasAuthority('BUSINESS') and @permissionUtils.canAccessBusinessData(@businessService.getBusinessById(#businessId).get().getBusinessOwner().getId()))")
    @Operation(summary = "根据店铺ID查询订单")
    public HttpResult<List<OrderResponseDTO>> getOrdersByBusiness(@PathVariable Long businessId) throws Exception{
        try {
            List<Order> orders = orderService.getOrdersByBusinessId(businessId);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询店铺订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/public/by-business/{businessId}/count")
    @PreAuthorize("permitAll()")
    @Operation(summary = "公开：返回店铺订单数量（不含明细）")
    public HttpResult<java.util.Map<String, Long>> getBusinessOrderCount(@PathVariable Long businessId) throws Exception {
        try {
            long count = orderService.countOrdersByBusinessId(businessId);
            return HttpResult.success(java.util.Collections.singletonMap("count", count));
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询店铺订单数失败: " + e.getMessage());
        }
    }

    @GetMapping("/by-status")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "根据订单状态查询订单")
    public HttpResult<List<OrderResponseDTO>> getOrdersByStatus(@RequestParam Integer orderStatus) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            List<Order> orders = orderService.getOrdersByUserIdAndStatus(user.getId(), orderStatus);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "根据状态查询订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/by-date-range")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "根据日期范围查询订单")
    public HttpResult<List<OrderResponseDTO>> getOrdersByDateRange(@RequestParam String startDate, 
                                                                  @RequestParam String endDate) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            List<Order> orders = orderService.getOrdersByUserIdAndDateRange(user.getId(), startDate, endDate);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "根据日期范围查询订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/by-total-range")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "根据订单金额范围查询订单")
    public HttpResult<List<OrderResponseDTO>> getOrdersByTotalRange(@RequestParam BigDecimal minTotal, 
                                                                   @RequestParam BigDecimal maxTotal) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            List<Order> orders = orderService.getOrdersByUserIdAndTotalRange(user.getId(), minTotal, maxTotal);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "根据金额范围查询订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/recent")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "查询最近的订单")
    public HttpResult<List<OrderResponseDTO>> getRecentOrders(@RequestParam(defaultValue = "10") Integer limit) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            List<Order> orders = orderService.getRecentOrdersByUserId(user.getId(), limit);
            List<OrderResponseDTO> responseDTOs = orderMapper.toOrderResponseDTOs(orders);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询最近订单失败: " + e.getMessage());
        }
    }

    @GetMapping("/statistics")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "查询订单统计信息")
    public HttpResult<Map<String, Object>> getOrderStatistics() throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            Map<String, Object> statistics = orderService.getOrderStatisticsByUserId(user.getId());
            return HttpResult.success(statistics);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询订单统计失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or @permissionUtils.canAccessOrderData(@orderService.getOrderById(#id).get().getCustomer().getId())")
    @Operation(summary = "修改订单")
    public HttpResult<OrderResponseDTO> updateOrder(@PathVariable Long id, @RequestBody Order order) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            order.setId(id);
            order.setUpdater(user.getId());
            order.setUpdateTime(LocalDateTime.now());
            Order updatedOrder = orderService.updateOrder(order);
            OrderResponseDTO responseDTO = orderMapper.toOrderResponseDTO(updatedOrder);
            return HttpResult.success(responseDTO);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "修改订单失败: " + e.getMessage());
        }
    }

    @PatchMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or @permissionUtils.canAccessOrderData(@orderService.getOrderById(#id).get().getCustomer().getId())")
    @Operation(summary = "部分修改订单")
    public HttpResult<OrderResponseDTO> partiallyUpdateOrder(@PathVariable Long id, @RequestBody Order order) throws Exception{
        try {
            User user = userService.getUserWithAuthorities().get();
            Optional<Order> existingOrder = orderService.getOrderById(id);
            if (existingOrder.isPresent()) {
                Order orderToUpdate = existingOrder.get();
                // 只更新非空字段
                if (order.getOrderTotal() != null) {
                    orderToUpdate.setOrderTotal(order.getOrderTotal());
                }
                if (order.getOrderDate() != null) {
                    orderToUpdate.setOrderDate(order.getOrderDate());
                }
                if (order.getOrderState() != null) {
                    orderToUpdate.setOrderState(order.getOrderState());
                }
                if (order.getCustomer() != null) {
                    orderToUpdate.setCustomer(order.getCustomer());
                }
                if (order.getBusiness() != null) {
                    orderToUpdate.setBusiness(order.getBusiness());
                }
                if (order.getDeliveryAddress() != null) {
                    orderToUpdate.setDeliveryAddress(order.getDeliveryAddress());
                }
                if (order.getDeleted() != null) {
                    orderToUpdate.setDeleted(order.getDeleted());
                }
                orderToUpdate.setUpdater(user.getId());
                orderToUpdate.setUpdateTime(LocalDateTime.now());
                Order updatedOrder = orderService.updateOrder(orderToUpdate);
                OrderResponseDTO responseDTO = orderMapper.toOrderResponseDTO(updatedOrder);
                return HttpResult.success(responseDTO);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "订单不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "部分修改订单失败: " + e.getMessage());
        }
    }

}
